﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using BudgetMealsModels.Entities;
using BudgetMealsModels.Abstract;
using BudgetMealsUI.Models;
using System.Web.Security;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Text.RegularExpressions;

namespace BudgetMealsUI.Controllers
{
    public class UserController : Controller
    {
        private IUserRepository repository;
        private const int pageSize = 12;
        public UserController(IUserRepository repo)
        {
            repository = repo;
        }


        [Authorize(Roles="Admin")]
        public ActionResult Index(int page = 1)
        {
            ListViewModel<User> model = new ListViewModel<User>
            {
                Info = new PagingInfo { CurrentPage = page, ItemsPerPage = pageSize, TotalItems = repository.Users.Count() },
                PageItems = repository.Users.OrderBy(x => x.UserName).Skip(pageSize * (page - 1)).Take(pageSize)
            };
            return View(model);
        }

        public ActionResult Profile(int id)
        {
            User user = repository.Users.FirstOrDefault(x => x.UserID == id);
            return View(user);
        }

        public ActionResult Create()
        {
            if (Session["CurrentUser"] != null)
                return RedirectToAction("Index", "Home");
            return View(new FormUser());
        }

        [HttpPost]
        public ActionResult Create(FormUser user, HttpPostedFileBase image)
        {
            if (!Regex.IsMatch(user.Email, @"^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$"))
            {
                ModelState.AddModelError("", "E-mail is not in the right format.");
            }
            MembershipUserCollection existingUsers = Membership.GetAllUsers();
            foreach (MembershipUser e in existingUsers)
            {
                if (e.UserName == user.UserName)
                {
                    ModelState.AddModelError("", "Username is already taken.");
                }
            }
            if (image != null && image.ContentType != "image/jpg" && image.ContentType != "image/jpeg" && image.ContentType != "image/png")
            {
                ModelState.AddModelError("", "Invalid file extension for profile picture.  Must be .jpeg, .jpg, or .png");
            }
            if (ModelState.IsValid)
            {
                if (image != null)
                {
                    System.Drawing.Image beginImage = System.Drawing.Image.FromStream(image.InputStream);
                    Bitmap resizedImage = ResizeImage(beginImage);
                    user.ImageMimeType = image.ContentType;
                    user.ImageData = (byte[])System.ComponentModel.TypeDescriptor.GetConverter(resizedImage).ConvertTo(resizedImage, typeof(byte[]));
                }
                MembershipUser u = Membership.CreateUser(user.UserName, user.Password);
                
                User newUser = new User
                {
                    FirstName = user.FirstName,
                    Biography = user.Biography,
                    Email = user.Email,
                    ImageData = user.ImageData,
                    ImageMimeType = user.ImageMimeType,
                    LastName = user.LastName,
                    UserName = user.UserName
                };
                int id = repository.Edit(newUser);
                Membership.ValidateUser(user.UserName, user.Password);
                HttpContext.Session["CurrentUser"] = id;
                HttpContext.Session["CurrentUserName"] = user.UserName;
                FormsAuthentication.SetAuthCookie(user.UserName, false);
                return RedirectToAction("Index", "Home");
            }

            return View(user);
        }

        
        public ActionResult Edit(int id)
        {
            User user = repository.Users.FirstOrDefault(x => x.UserID == id);
            return View(user);
        }

        [HttpPost]
        public ActionResult Edit(User user, HttpPostedFileBase image)
        {
            if (ModelState.IsValid)
            {
                if (image != null)
                {
                    System.Drawing.Image beginImage = System.Drawing.Image.FromStream(image.InputStream);
                    Bitmap resizedImage = ResizeImage(beginImage);
                    user.ImageMimeType = image.ContentType;
                    user.ImageData = (byte[])System.ComponentModel.TypeDescriptor.GetConverter(resizedImage).ConvertTo(resizedImage, typeof(byte[]));
                }
                repository.Edit(user);
                return RedirectToAction("Profile", new { id=user.UserID });
            }
            return View(user);
        }
        [Authorize]
        [HttpPost]
        public ActionResult Delete(int id)
        {
            User user = repository.Users.FirstOrDefault(p => p.UserID == id);
            if (user != null)
            {
                Membership.DeleteUser(user.UserName);
                repository.Delete(user);
            }
            return RedirectToAction("Index");
        }

        public ActionResult ShowRecipes(int id)
        {
            User user = repository.Users.FirstOrDefault(p => p.UserID == id);
            if (user.Recipes == null)
            {
                user.Recipes = new List<Recipe>();
            }
            return PartialView(user.Recipes);
        }

        public ActionResult ShowMeals(int id)
        {
            User user = repository.Users.FirstOrDefault(u => u.UserID == id);
            if (user.Meals == null)
            {
                user.Meals = new List<Meal>();
            }
            return PartialView(user.Meals);
        }

        public FileContentResult GetImage(int userId)
        {
            User user = repository.Users.FirstOrDefault(u => u.UserID == userId);
            if (user != null)
            {
                return File(user.ImageData, user.ImageMimeType);
            }
            return null;
        }

        public Bitmap ResizeImage(System.Drawing.Image srcImage)
        {
            int newHeight = FindNewHeightOrWidth(srcImage.Height);
            int newWidth = FindNewHeightOrWidth(srcImage.Width);
            Bitmap newImage = new Bitmap(newWidth, newHeight);
            using (Graphics gr = Graphics.FromImage(newImage))
            {
                gr.SmoothingMode = SmoothingMode.AntiAlias;
                gr.InterpolationMode = InterpolationMode.HighQualityBicubic;
                gr.PixelOffsetMode = PixelOffsetMode.HighQuality;
                gr.DrawImage(srcImage, new Rectangle(0, 0, newWidth, newHeight));
            }
            return newImage;
        }

        public int FindNewHeightOrWidth(double value)
        {
            while (value > 600)
            {
                value = value / 1.1;
            }
            return (int)Math.Round(value);
        }
    }
}
